package com.xbongbong.pro.message.service.impl;

import com.alibaba.dingtalk.openapi.newmessage.entity.OA;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.message.domain.entity.PushEntity;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.util.URLEncodeUtils;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.MessageErrorCodeEnum;
import com.xbongbong.pro.message.enums.DistributorWechatUrlEnum;
import com.xbongbong.pro.message.enums.MessagePushRefTypeEnum;
import com.xbongbong.pro.message.enums.MessageWebPcUrlEnum;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.DistributorMessageRabbitMqDTO;
import com.xbongbong.pro.message.service.DistributorMessageService;
import com.xbongbong.pro.message.service.PushService;
import com.xbongbong.saas.enums.DingtalkPageUrlEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service("distributorMessageServiceImpl")
public class DistributorMessageServiceImpl implements DistributorMessageService {

    private static final Logger LOG = LoggerFactory.getLogger(DistributorMessageServiceImpl.class);

    @Resource
    private PushService pushService;

    @Async(value = "messageThreadPool")
    @Override
    public void pushDistributorMessage(DistributorMessageRabbitMqDTO messageRabbitMqDTO, PushTypeEnum pushTypeEnum) throws XbbException {
        String corpid = messageRabbitMqDTO.getCorpid();
        List<String> userIds = messageRabbitMqDTO.getUserIds();
        List<Long> refIds = messageRabbitMqDTO.getRefIds();
        if (StringUtil.isEmpty(corpid)) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage error,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380007, MessageErrorCodeEnum.API_ERROR_380007.getMsg() + pushTypeEnum));
            return;
        }
        if (userIds == null || userIds.size() == 0) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage error,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380005, MessageErrorCodeEnum.API_ERROR_380005.getMsg() + pushTypeEnum));
            return;
        }
        if (userIds.size() > 100) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage error,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380008, MessageErrorCodeEnum.API_ERROR_380008.getMsg() + pushTypeEnum));
            return;
        }
        if (refIds == null || refIds.size() == 0) {
            LOG.warn("com.xbongbong.pro.message.service.impl.MessageServiceImpl.delayPushDingtalkOAMessage error,  MessageRabbitMqDTO = " + JSON.toJSONString(messageRabbitMqDTO), new XbbException(MessageErrorCodeEnum.API_ERROR_380006, MessageErrorCodeEnum.API_ERROR_380006.getMsg() + pushTypeEnum));
            return;
        }

        Integer isRemind = messageRabbitMqDTO.getRemind();
        Long pushTime = messageRabbitMqDTO.getPushTime();
        String title = messageRabbitMqDTO.getTitle();
        String content = messageRabbitMqDTO.getContent();
        PushRefTypePojo.Options options = messageRabbitMqDTO.getOptions();

        List<OA.Body.Form> formList = messageRabbitMqDTO.getForm();

        // 后续增加微信小程序推送消息,暂时使用钉钉推送的方法，后续可改
        OA oaMessage = formatWechatMessage(pushTypeEnum, title, content, formList, options, corpid, false);

        String type = formatRefType(pushTypeEnum, options, false);

        Long now = DateTimeUtil.getInt();
        PushEntity pushEntity = new PushEntity();
        pushEntity.setCorpid(corpid);
        pushEntity.setRefEntity(pushTypeEnum.getCode());
        pushEntity.setRefId(refIds.get(0));
        pushEntity.setRefArray(JSONObject.toJSONString(refIds));

        pushEntity.setRefType(type);
        pushEntity.setType(pushTypeEnum.getCode());
        pushEntity.setSubType(pushTypeEnum.getSubCode());
        pushEntity.setPushObject(JSONObject.toJSONString(userIds));
        pushEntity.setMsg(JSONObject.toJSONString(oaMessage));
        pushEntity.setPushTime(pushTime);
        pushEntity.setIsPush(0);
        pushEntity.setIsRemind(isRemind);
        pushEntity.setAddTime(now);
        pushEntity.setUpdateTime(now);

        if (Objects.equals(isRemind, 1)) {
            //如果是提醒的消息，直接保存不推送，需要在用户设置的时间推送，走轮询
            pushService.save(pushEntity);
        } else {
            //推送微信小程序消息消息
            try {
                String userIdsStr = null;
                for (String id : userIds) {
                    if (userIdsStr == null) {
                        userIdsStr = id;
                    } else {
                        userIdsStr += "," + id;
                    }
                }
                // 后续改为微信小程序推送
//            CorpConversationHelper.SendResponse sendResponse = messageNewService.dingtalkOAMessagePushToUserAndDept(corpid, oaMessage, userIdsStr, null);
//            if (sendResponse != null) {
//                pushEntity.setTaskId(sendResponse.getTaskId());
//            }
                //推送成功is_push设置为1
                pushEntity.setIsPush(1);
                //push,push_link表入库
                pushService.save(pushEntity);
            } catch (XbbException e) {
                pushService.save(pushEntity);
                throw e;
            } catch (Exception e) {
                pushService.save(pushEntity);
                throw e;
            }
        }
    }

    /**
     * Description: 封装消息refType字段用于系统内跳转
     * @param pushTypeEnum 推送枚举
     * @param options 参数
     * @return java.lang.String
     * @throws XbbException XbbException
     * @author 魏荣杰
     * @date 2019/4/8 11:25
     * @since v1.0
     */
    private String formatRefType(PushTypeEnum pushTypeEnum, PushRefTypePojo.Options options, boolean isCreator) throws XbbException {
        PushRefTypePojo pushRefTypePojo = new PushRefTypePojo();
        PushRefTypePojo.CommonDetailOptions commonDetailOption = new PushRefTypePojo.CommonDetailOptions();
        Map<String, Object> optionMap;
        switch (pushTypeEnum) {
            // 订货单
            case DISTRIBUTOR_ORDER_PUSH:
            case DISTRIBUTOR_ORDER_ADD_PUSH:
            case DISTRIBUTOR_ORDER_REVIEW_PUSH:
            case DISTRIBUTOR_ORDER_ABANDONED_PUSH:
            case DISTRIBUTOR_ORDER_CLOSE_PUSH:
            case DISTRIBUTOR_ORDER_SHIP_PUSH:
            case DISTRIBUTOR_COUPON_USE_PUSH:
                BeanUtil.copyProperties(options, commonDetailOption);
                optionMap = BeanUtil.convertBean2Map(commonDetailOption);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_DETAIL.getAlias());

                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_COMMON_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setOptions(commonDetailOption);
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.ORDER_DETAIL.getRoot() + DistributorWechatUrlEnum.ORDER_DETAIL.getUrl(), options.getDataId()));
                break;
            case DISTRIBUTOR_MARKETING_ACTIVITY_MANAGEMENT_PUSH:
            case DISTRIBUTOR_MARKETING_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
                PushRefTypePojo.CommonDetailOptions commonDetailOption1 = new PushRefTypePojo.CommonDetailOptions();
                BeanUtil.copyProperties(options, commonDetailOption1);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_LIST.getAlias());

                pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_COUPON_LIST.getUrl());
                pushRefTypePojo.setOptions(commonDetailOption1);
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.COUPON_DETAIL.getRoot() + DistributorWechatUrlEnum.COUPON_DETAIL.getUrl(), options.getDataId()));
                break;
            case DISTRIBUTOR_PROMOTION_ACTIVITY_MANAGEMENT_ONLINE_PUSH:
            case DISTRIBUTOR_PROMOTION_ACTIVITY_MANAGEMENT_PUSH:
                PushRefTypePojo.CommonDetailOptions commonDetailOption2 = new PushRefTypePojo.CommonDetailOptions();
                BeanUtil.copyProperties(options, commonDetailOption2);
                optionMap = BeanUtil.convertBean2Map(commonDetailOption2);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_LIST.getAlias());

                pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_MALL_LIST.getUrl());
                pushRefTypePojo.setOptions(commonDetailOption2);
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.MALL_DETAIL.getRoot() + DistributorWechatUrlEnum.MALL_DETAIL.getUrl(), options.getDataId()));
                break;
            case DISTRIBUTOR_COUPON_GET_PUSH:
                pushRefTypePojo.setOptions(commonDetailOption);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_LIST.getAlias());
                pushRefTypePojo.setPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_MALL_LIST.getUrl());
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.MALL_DETAIL.getRoot() + DistributorWechatUrlEnum.MALL_DETAIL.getUrl()));
                break;
            case DISTRIBUTOR_REFUND_REVIEW_PUSH:
            case DISTRIBUTOR_REFUND_ABANDONED_PUSH:
            case DISTRIBUTOR_REFUND_CLOSE_PUSH:
                BeanUtil.copyProperties(options, commonDetailOption);
                optionMap = BeanUtil.convertBean2Map(commonDetailOption);

                pushRefTypePojo.setOptions(commonDetailOption);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_DETAIL.getAlias());
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_COMMON_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.RETURN_DETAIL.getRoot() + DistributorWechatUrlEnum.RETURN_DETAIL.getUrl(), options.getDataId()));
                break;
            case STATEMENT_GENERATE_PUSH:
            case STATEMENT_REMIND_CONFIRM_PUSH:
            case STATEMENT_VALET_CONFIRM_PUSH:
            case STATEMENT_REGENERATE_PUSH:
                BeanUtil.copyProperties(options, commonDetailOption);
                optionMap = BeanUtil.convertBean2Map(commonDetailOption);

                pushRefTypePojo.setOptions(commonDetailOption);
                pushRefTypePojo.setType(MessagePushRefTypeEnum.COMMON_DETAIL.getAlias());
                pushRefTypePojo.setPcUrl(formatPcUrl(MessageWebPcUrlEnum.DISTRIBUTOR_STATEMENT_DETAIL.getUrl(), optionMap));
                pushRefTypePojo.setWeChatUrl(String.format(DistributorWechatUrlEnum.STATEMENT_DETAIL.getRoot() + DistributorWechatUrlEnum.STATEMENT_DETAIL.getUrl(), options.getDataId()));
                break;
            case UNKNOWN:
                break;
            default:
        }
        return JSON.toJSONString(pushRefTypePojo);
    }

    private String formatPcUrl(String url, Map<String, Object> options) {
        String params = null;
        for (Map.Entry<String, Object> entry : options.entrySet()) {
            if (params == null) {
                params = entry.getKey() + "=" + entry.getValue();
            } else {
                params += "&" + entry.getKey() + "=" + entry.getValue();
            }
        }
        return url + "?" + params;
    }

    /**
     * Description: oa消息体封装
     * @param pushTypeEnum 消息类型
     * @param title 消息标题
     * @param content 消息内容
     * @param formList 消息form部分
     * @param options
     * @param corpid
     * @return com.alibaba.dingtalk.openapi.message.OAMessage
     * @author 魏荣杰
     * @date 2019/3/4 10:00
     * @since v1.0
     */
    private OA formatWechatMessage(PushTypeEnum pushTypeEnum, String title, String content, List<OA.Body.Form> formList, PushRefTypePojo.Options options, String corpid, boolean isCreator) {
        String messageUrl = "";
        String pcMessageUrl = "";
        OA oaMessage = new OA();
        OA.Body body = new OA.Body();
        body.setForm(formList);
        body.setTitle(title);
        body.setContent(content);
        body.setAuthor(I18nMessageUtil.getMessage(I18nStringConstant.XBB_CRM));
        oaMessage.setBody(body);
        //OA消息封装
        switch (pushTypeEnum) {
            case DISTRIBUTOR_ORDER_PUSH:
            case DISTRIBUTOR_ORDER_ADD_PUSH:
            case DISTRIBUTOR_ORDER_REVIEW_PUSH:
            case DISTRIBUTOR_ORDER_ABANDONED_PUSH:
            case DISTRIBUTOR_ORDER_CLOSE_PUSH:
            case DISTRIBUTOR_ORDER_SHIP_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.ORDER_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case DISTRIBUTOR_REFUND_REVIEW_PUSH:
            case DISTRIBUTOR_REFUND_ABANDONED_PUSH:
            case DISTRIBUTOR_REFUND_CLOSE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.RETURN_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            case STATEMENT_GENERATE_PUSH:
            case STATEMENT_REMIND_CONFIRM_PUSH:
            case STATEMENT_VALET_CONFIRM_PUSH:
            case STATEMENT_REGENERATE_PUSH:
                messageUrl += String.format(DingtalkPageUrlEnum.STATEMENT_DETAIL.getUrl(), options.getDataId(), options.getAppId(), options.getMenuId(), options.getFormId());
                break;
            default:
                messageUrl += String.format(DingtalkPageUrlEnum.INDEX.getUrl(), corpid);
                break;
        }

        //非邀请在右侧打开
        if (!Objects.equals(pushTypeEnum, PushTypeEnum.INVITE_STAFF_PUSH)) {
            pcMessageUrl += URLEncodeUtils.encodeURL(messageUrl) + "&pc_slide=true";
        }

        oaMessage.setMessageUrl(messageUrl);
        oaMessage.setPcMessageUrl(pcMessageUrl);

        return oaMessage;
    }
}
